<script setup>
import part from './part/index.vue';
import { ref, toRefs, watch } from 'vue';
import attr from './part/attr.vue';
import ApiData from './components/apiData.vue';
import dataInfo from './part/dataInfo.json'
import canvasBg from './components/canvasBg.vue';
import { runApiDataResult, broadcastData } from './tools';
import { apiData as storApiData } from './stores/apiData'
import { ElSplitter,ElSplitterPanel,ElScrollbar,ElSegmented,ElButton} from 'element-plus'
import html2canvas from 'html2canvas';
const setInfo = storApiData().setInfo;


// 标签选项
const tabOptions = ref([
  { label: '属性', value: '1' },
  { label: '数据', value: '3' },
  { label: '背板', value: '4' }
]);

const activeTab = ref('1');

const { options, apiList, busStore, privateStore } = toRefs(dataInfo);

const partData = ref({
  name: dataInfo.name,
  version: dataInfo.version,
  describe: dataInfo.describe,
  author: dataInfo.author,
})


// 背景数据
const canvasdata = ref({})
const canvasdata_ref = ref(null);

// 属性配置
const attrRef = ref(null);
const optionsData = ref({});

// 数据配置
const apiDataRef = ref(null);
const apiDataList = ref([]);

watch([() => canvasdata_ref.value?.canvasdata, () => attrRef.value?.options, () => apiDataRef.value?.apiData], ([newCanvasdata, newOption, newApiData], [oldCanvasdata, oldOptions, oldApiData]) => {
  canvasdata.value = newCanvasdata;
  optionsData.value = newOption;
  apiDataList.value = newApiData;
}, { deep: true })
const apiDataListOptions = runApiDataResult;
watch(() => apiDataList, (newValue, oldValue) => {
  let data = [];
  if (newValue.value.length > 0) {
    newValue.value.forEach(item => {
      data.push({ ...item })
    })
  }
  setInfo(data)
}, { deep: true })
watch(() => broadcastData.value, (newValue, oldValue) => {
  busStore.value = { ...busStore, ...newValue }
}, { deep: true })

const canvasElements = ref(null);// 保存为PNG格式
async function saveCard() {
  const element = canvasElements.value;
  html2canvas(element, {
    useCORS: true,
    allowTaint: true,
    backgroundColor: null, // 保持透明背景（PNG特性）
    logging: false
  }).then((canvas) => {
    // 调整：压缩函数指定为PNG格式
    compressToTargetSize(canvas, 60, 'image/png').then((compressedBlob) => {
      if (compressedBlob) {
        // 调整：下载时指定为PNG扩展名
        downloadBlobAsImage(compressedBlob, 'png');
      } else {
        console.error('压缩后的Blob生成失败');
      }
    });
  });
}

// 调整：增加格式参数，默认PNG
const compressToTargetSize = (canvas, targetSizeKB = 100, mimeType = 'image/png') => {
  return new Promise((resolve) => {
    const targetSizeBytes = targetSizeKB * 1024;
    // PNG是无损压缩，quality参数仅对JPEG有效，这里保留用于尺寸调整
    let quality = 0.9; 
    let maxIterations = 8;
    let width = canvas.width;
    let height = canvas.height;
    let attempts = 0;

    const maxDimension = 1200;
    if (width > maxDimension || height > maxDimension) {
      const ratio = maxDimension / Math.max(width, height);
      width = Math.floor(width * ratio);
      height = Math.floor(height * ratio);
    }

    const adjustQuality = () => {
      attempts++;

      const tempCanvas = document.createElement('canvas');
      tempCanvas.width = width;
      tempCanvas.height = height;
      const ctx = tempCanvas.getContext('2d');
      ctx.drawImage(canvas, 0, 0, width, height);

      // 关键调整：指定为PNG格式（mimeType）
      tempCanvas.toBlob((blob) => {
        if (!blob) {
          console.error('压缩失败，Blob生成错误');
          resolve(null);
          return;
        }

        if (blob.size <= targetSizeBytes || attempts >= maxIterations) {
          resolve(blob);
          return;
        }
        width = Math.floor(width * 0.85); // 每次缩小15%
        height = Math.floor(height * 0.85);
        adjustQuality();
      }, mimeType); // 传入PNG格式
    };

    adjustQuality();
  });
};

// 调整：支持指定文件扩展名
function downloadBlobAsImage(blob, extension = 'png') {
  const url = URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.href = url;
  // 文件名以.png结尾
  link.download = `preview.${extension}`;
  
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(url);
}
</script>

<template>
  <div class="canvas-editor">
    <div class="leftMenu">
            <div class="leftMenuContenter">
                <div>
                    <div style="margin-top: 20px;">
                        <el-button type="primary"
                            @click="saveCard()">生成预览图</el-button>
                    </div>
                </div>
                <br></br>
            </div>
        </div>
    <el-splitter>
      <!-- 左侧画布区域 -->
      <el-splitter-panel size="80%">
        <div class="contenter_box-container" ref="canvasElements">
          <div class="contenter_box"
            :style="{ ...canvasdata, width: canvasdata.width + 'px', height: canvasdata.height + 'px' }">
            <part :options="optionsData" :apiData="apiDataListOptions" :ownStore="dataInfo" :busStore="busStore"
              :privateStore="privateStore">
            </part>
          </div>
        </div>
      </el-splitter-panel>

      <!-- 右侧资源面板 -->
      <el-splitter-panel :min="300">
        <div class="right-panel">
          <el-segmented v-model="activeTab" :options="tabOptions" block />
          <div class="resources-container" v-show="activeTab === '1'">
            <el-scrollbar height="100%">
              <attr ref="attrRef" :options="options" :apiList="apiDataList"></attr>
            </el-scrollbar>
          </div>
          <div class="resources-container" v-show="activeTab === '3'">
            <el-scrollbar height="100%">
              <ApiData ref="apiDataRef" :apiList="apiList"></ApiData>
            </el-scrollbar>
          </div>
          <div class="resources-container" v-show="activeTab === '4'">
            <el-scrollbar height="100%">
              <el-alert title="调试面板样式，不会被打包到最终的代码中！" style="margin: 0px 0 20px;" type="info" :closable="false" />
              <canvasBg ref="canvasdata_ref"></canvasBg>
            </el-scrollbar>
          </div>
        </div>
      </el-splitter-panel>
    </el-splitter>
  </div>
</template>
<style>
*{
  margin: 0;
  padding: 0;
}
</style>
<style scoped lang="scss">
.leftMenu {
  position: fixed;
  left: 0;
  top: 0;
  height: 100vh;
  width: 30px;
  opacity: 0;
  transition: all 0.3s ease;
  z-index: 10000;

  .leftMenuContenter {
    position: absolute;
    right: 0;
    top: 0;
    width: 100px;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;

    .saveButtom {
      width: 40px;
      height: 40px;
      text-align: center;
      line-height: 40px;
      cursor: pointer;
    }
  }
}

.leftMenu:hover {
  opacity: 1;
  width: 100px;
}
.canvas-editor {
  height: 100vh;
}

.resources-container {
  width: 90%;
  margin: 10px auto;
}

.contenter_box-container {
  height: 100%;
  width: 100%;
  position: relative;
}

.contenter_box {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
</style>